package com.quest.blockThread;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadProcessor {
    private static CountDownLatch latch = new CountDownLatch(1);
    private static ReentrantLock lock = new ReentrantLock();
    private static Condition conditionA = lock.newCondition();
    private static Condition conditionB = lock.newCondition();
    private static Condition conditionC = lock.newCondition();
    private static int count = 10;//计数
    private static int flag = 1;//保证顺序执行

    private static class A implements Runnable {
        @Override
        public void run() {
            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            while (count > 0) {
                lock.lock();
                try {
                    if(flag != 1){
                        conditionA.await();//阻塞A
                    }
                    System.out.print("A");
                    flag = 2;
                    conditionB.signal();//释放B
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }

            }
        }
    }

    private static class B implements Runnable {
        @Override
        public void run() {
            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            while (count > 0) {
                lock.lock();
                try {
                    if(flag != 2){
                        conditionB.await();//阻塞B
                    }
                    System.out.print("B");
                    flag = 3;
                    conditionC.signal();//释放C
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }

            }
        }
    }

    private static class C implements Runnable {
        @Override
        public void run() {
            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            while (count > 0) {
                lock.lock();
                count--;
                try {
                    if(flag != 3){
                        conditionC.await();//阻塞C
                    }
                    System.out.println("C");
                    flag = 1;
                    conditionA.signal();//释放A
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }

            }
        }
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(new A());
        Thread t2 = new Thread(new B());
        Thread t3 = new Thread(new C());
        t1.start();
        t2.start();
        t3.start();
        //阻塞保证线程同时启动
        latch.countDown();
    }

}
